﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WGMClient.HelperClasses;
using WGMClient.Properties;
using System.Text.RegularExpressions;
using System.Threading;
using System.Net;
using Microsoft.Win32;
using System.IO;
using System.Security.Cryptography;
using System.Media;
using System.Windows.Threading;
using System.Globalization;
using System.Reflection;

namespace WGMClient.Controls
{
    /// <summary>
    /// Interaction logic for InternalChatControl.xaml
    /// </summary>
    public partial class InternalChatControl : UserControl, IMessageListener
    {
        public bool IsMainWindow { get; set; }
        public BackgroundTextBlock AssociatedSelector { get; set; }
        public TabItem AssociatedTab { get; set; }
        private WGMLocalClient _associatedClient;
        private string _username;
        private int _ongoingXferCount = 0;
        DateTime _lastType = DateTime.Now;
        private List<KeyValuePair<string, DispatcherTimer>> _typingList = new List<KeyValuePair<string, DispatcherTimer>>();
        public WGMLocalClient AssociatedClient 
        {
            get { return _associatedClient; }
            set { _associatedClient = value; SetInfo(); } 
        }

        private void SetInfo()
        {      
            this.Dispatcher.Invoke
            (
                new Action(() =>
                {
                    _contactInfo.Text = AssociatedClient.DisplayName;
                    _contactInfo.SubText = AssociatedClient.DisplayStatus;
                    _username = AssociatedClient.Username;
                })
            );
        }

        public void SetImage(byte[] imageData)
        {
            this.Dispatcher.Invoke
            (
                new Action(() =>
                {
                    if (imageData != null)
                    {
                        if (!IsMainWindow)
                        {
                            _contactInfo.SetBackgroundImage(imageData);
                            AssociatedClient.ImageData = imageData;
                        }
                        else
                            _contactInfo.BackgroundImage = HelperClasses.HelperFunctions.GetBitmapFromImage(HelperClasses.HelperFunctions.ByteArrayToImage(imageData));
                    }
                    else
                        try
                        {
                            if (!IsMainWindow)
                            {
                                AssociatedClient.ImageData = null;
                                _contactInfo.SetBackgroundImage(null);
                            }
                        }
                        catch (Exception ex)
                        {
                        }
                    _contactInfo.HasImage = HelperClasses.Registry.Settings.ShowContactImages;
                })
            );
        }

        public InternalChatControl()
        {
            InitializeComponent();
            HelperClasses.Registry.RegisterListener(this);
            SetOutgoingTB();
            _incomingTB.Document.Blocks.Clear();
            _incomingTB.Document.LineHeight = 2;
        }

        private void SetOutgoingTB()
        {
            var myInfo = HelperClasses.Registry.MyInfo;
            if (myInfo != null)
            {
                _outgoingTB.FontSize = myInfo.FontSize;
                _outgoingTB.FontFamily = myInfo.FontFace;
                _outgoingTB.Foreground = new SolidColorBrush(myInfo.UserColor);
                _outgoingTB.FontStyle = myInfo.IsFontItalics ? FontStyles.Italic : FontStyles.Normal;
                _outgoingTB.FontWeight = myInfo.IsFontBold ? FontWeights.Bold : FontWeights.Normal;
            }
        }

        public void NotifyServerMessage(WGMSvc.WGMMessage message)
        {
            this.Dispatcher.Invoke
            (
                new Action
                (
                    delegate
                    {
                        switch (message.MessageType)
                        {
                            case WGMClient.WGMSvc.MessageTypes.SERVER_PROFILE_IMAGE_RESPONSE:
                                if (message.ReceiverLogon == _username)
                                    SetImage(message.Message as byte[]);
                                break;
                            case WGMClient.WGMSvc.MessageTypes.GLOBAL_MESSAGE:
                                if (IsMainWindow)
                                    ReceiveTextMessage(message);
                                break;
                            case WGMClient.WGMSvc.MessageTypes.PRIVATE_MESSAGE:
                                if ((message.SenderLogon.ToLower().Trim() == HelperClasses.Registry.Username.ToLower().Trim() && message.ReceiverLogon.ToLower().Trim() == AssociatedClient.Username.Trim().ToLower()) || (message.SenderLogon.Trim().ToLower() == AssociatedClient.Username.Trim().ToLower()))
                                    ReceiveTextMessage(message);
                                break;
                            case WGMClient.WGMSvc.MessageTypes.USER_LOGON:
                                if (!IsMainWindow && message.SenderLogon.Trim().ToLower() == AssociatedClient.Username.Trim().ToLower()) 
                                    WGMClient.HelperClasses.Registry.MainWindow.SetClientOnline( AssociatedSelector, true, ClientState.ONLINE);
                                break;
                            case WGMClient.WGMSvc.MessageTypes.USER_LEAVING:
                                if (!IsMainWindow && message.SenderLogon.Trim().ToLower() == AssociatedClient.Username.Trim().ToLower())
                                    WGMClient.HelperClasses.Registry.MainWindow.SetClientOnline(AssociatedSelector, false, ClientState.OFFLINE);
                                break;
                            case WGMClient.WGMSvc.MessageTypes.SERVER_PROFILE_RESPONSE:
                                if (!IsMainWindow && message.SenderLogon.Trim().ToLower() == AssociatedClient.Username.Trim().ToLower())
                                {
                                    HelperClasses.Registry.MainWindow.UpdateContactSelector(message.Message as WGMSvc.WGMMember);
                                    SetInfo();                                    
                                }
                                break;
                            case WGMClient.WGMSvc.MessageTypes.USER_CHANGED_IMAGE:
                                if (!IsMainWindow && message.SenderLogon.Trim().ToLower() == AssociatedClient.Username.Trim().ToLower())
                                {                                    
                                    if (AssociatedTab.IsSelected)
                                    {
                                        HelperClasses.Registry.Engine.SendMessageToServer(new WGMClient.WGMSvc.WGMMessage() { MessageType = WGMClient.WGMSvc.MessageTypes.USER_REQUEST_PROFILE_IMAGE, SenderLogon = HelperClasses.Registry.Username, ReceiverLogon = AssociatedClient.Username, SenderTimeStamp = DateTime.Now });
                                    }
                                    else
                                    {
                                        AssociatedClient.FirstImageCheckCompleted = false;
                                    }                                    
                                }
                                break;
                            case WGMClient.WGMSvc.MessageTypes.PRIVATE_FILE_XFER:
                                if ((message.SenderLogon.ToLower().Trim() == HelperClasses.Registry.Username.ToLower().Trim() && message.ReceiverLogon.ToLower().Trim() == AssociatedClient.Username.Trim().ToLower()) || (message.SenderLogon.Trim().ToLower() == AssociatedClient.Username.Trim().ToLower()))
                                    ReceiveFileTransfer(message);
                                break;
                            case WGMClient.WGMSvc.MessageTypes.GLOBAL_FILE_XFER:
                                if(IsMainWindow)
                                    ReceiveFileTransfer(message);
                                break;
                            case WGMClient.WGMSvc.MessageTypes.USER_TYPING_GLOBAL:
                                if (IsMainWindow && (message.SenderLogon.ToLower().Trim() != WGMClient.HelperClasses.Registry.Username.ToLower().Trim()))
                                    AddUserToTypingList(message.SenderLogon);
                                break;
                            case WGMClient.WGMSvc.MessageTypes.USER_TYPING_PRIVATE:
                                if (message.SenderLogon.ToLower().Trim() == AssociatedClient.Username.ToLower().Trim())
                                {
                                    AddUserToTypingList(message.SenderLogon);
                                }
                                break;
                        }
                    }
                )
            );
        }

        private void AddUserToTypingList(string username)
        {

            DispatcherTimer typing = new DispatcherTimer();
            typing.Interval = TimeSpan.FromSeconds(3);
            typing.Tick += new EventHandler(typing_Tick);
            KeyValuePair<string, DispatcherTimer> kvp = new KeyValuePair<string, DispatcherTimer>(username, typing);
            _typingList.Add(kvp);
            typing.Tag = kvp;
            typing.Start();
            OnTypingListChanged();
        }

        void typing_Tick(object sender, EventArgs e)
        {
            DispatcherTimer timer = sender as DispatcherTimer;
            timer.Stop();
            KeyValuePair<string, DispatcherTimer> kvp =(KeyValuePair<string, DispatcherTimer>) timer.Tag;
            _typingList.Remove(kvp);
            OnTypingListChanged();
            
        }

        private void OnTypingListChanged()
        {

            List<string> typingList = new List<string>();
            for (int count = 0; count < _typingList.Count; count++)
            {
                var sender = HelperClasses.Registry.MainWindow.GetCLItem(_typingList[count].Key);
                if (sender != null)
                    typingList.Add(sender.AssociatedClient.DisplayName);
            }
            typingList = typingList.Distinct().ToList();
            if (typingList.Count > 0)
            {
                _typingListTb.Text = "";
                foreach (var typer in typingList)
                {
                    _typingListTb.Text += typer + ", ";
                }
                _typingListTb.Text = _typingListTb.Text.Substring(0, _typingListTb.Text.Length - 2);
                if(typingList.Count > 1)
                    _typingListTb.Text += " are typing.";
                else
                    _typingListTb.Text += " is typing.";
            }
            else
                _typingListTb.Text = "";
        }

        private void ReceiveFileTransfer(WGMClient.WGMSvc.WGMMessage message)
        {
            try
            {
                WGMLocalClient senderInfo;
                var sender = HelperClasses.Registry.MainWindow.GetCLItem(message.SenderLogon);
                if (sender == null)
                    senderInfo = HelperClasses.Registry.MyInfo;
                else
                    senderInfo = sender.AssociatedClient;
                if (senderInfo == null)
                    return;
                Paragraph para = new Paragraph();

                SolidColorBrush introBrush = new SolidColorBrush(Colors.Red);

                SolidColorBrush messageBrush = new SolidColorBrush(senderInfo.UserColor);

                string runIntro = "";
                if (HelperClasses.Registry.Settings.ShowMessageTimeStamps == true)
                    runIntro += "<" + message.ServerTimeStamp + "> ";

                Run introRun = new Run(runIntro + senderInfo.DisplayName + " is sending you a file:\r\n");
                introRun.FontFamily = new FontFamily(HelperClasses.Registry.Settings.SystemFontFamily);
                introRun.FontSize = HelperClasses.Registry.Settings.SystemFontSize;
                introRun.Foreground = introBrush;
                if (HelperClasses.Registry.Settings.IsSystemFontBold)
                    introRun.FontWeight = FontWeights.Bold;
                if (HelperClasses.Registry.Settings.IsSystemFontItalics)
                    introRun.FontStyle = FontStyles.Italic;
                para.Inlines.Add(introRun);

                string messageContent = "File name: " + message.ExtraInfo1 + "\nFile Size: " + message.ExtraInfo2;
                Run fileRun = new Run(messageContent);
                fileRun.FontFamily = new FontFamily(HelperClasses.Registry.Settings.SystemFontFamily);
                fileRun.FontSize = HelperClasses.Registry.Settings.SystemFontSize;
                fileRun.Foreground = messageBrush;

                para.Inlines.Add(fileRun);

                Hyperlink downloadLink = new Hyperlink(new Run("\r\nClick here to download now."));
                downloadLink.FontFamily = introRun.FontFamily;
                downloadLink.FontStyle = introRun.FontStyle;
                downloadLink.FontSize = introRun.FontSize;
                downloadLink.TextDecorations = introRun.TextDecorations;
                downloadLink.Foreground = new SolidColorBrush(Colors.Blue);

                Hyperlink openLink = new Hyperlink(new Run(""));
                openLink.FontFamily = introRun.FontFamily;
                openLink.FontStyle = introRun.FontStyle;
                openLink.FontSize = introRun.FontSize;
                openLink.TextDecorations = introRun.TextDecorations;
                openLink.IsEnabled = false;
                openLink.Foreground = new SolidColorBrush(Colors.Blue);

                Hyperlink cancelLink = new Hyperlink(new Run(""));
                cancelLink.FontFamily = introRun.FontFamily;
                cancelLink.FontStyle = introRun.FontStyle;
                cancelLink.FontSize = introRun.FontSize;
                cancelLink.TextDecorations = introRun.TextDecorations;
                cancelLink.IsEnabled = false;
                cancelLink.Foreground = new SolidColorBrush(Colors.Blue);

                string downloadURL = "http://hartlabs.com/downloads/wgm/uploads/" + message.ExtraInfo3;
                string baseDir = (HelperClasses.Registry.WorkingDir + "Received Files");
                string userDir = baseDir + "\\" + message.SenderLogon;


                ProgressBar pb = new ProgressBar();
                pb.Width = 200;
                pb.Height = 5;
                pb.Maximum = 100;
                pb.Minimum = 0;

                Run downloadedBytesIntroRun = new Run("\r\nDownloaded: ");
                Run downloadedBytesRun = new Run();

                Run downloadSpeedIntroRun = new Run("\r\nDownload Speed: ");
                Run downloadSpeedRun = new Run();

                Run timeLeftIntroRun = new Run("\r\nEstimated Time Left: ");
                Run timeLeftRun = new Run();


                downloadLink.Click += (clickSender, clickParms) =>
                                      {
                                          _ongoingXferCount++;
                                          para.Inlines.Add(downloadedBytesIntroRun);
                                          para.Inlines.Add(downloadedBytesRun);
                                          para.Inlines.Add(downloadSpeedIntroRun);
                                          para.Inlines.Add(downloadSpeedRun);
                                          para.Inlines.Add(timeLeftIntroRun);
                                          para.Inlines.Add(timeLeftRun);
                                          para.Inlines.Add(new Run(Environment.NewLine));
                                          para.Inlines.Add(pb);
                                          para.Inlines.Add(cancelLink);
                                          DateTime startTime = DateTime.Now;
                                          pb.Visibility = Visibility.Visible;
                                          downloadLink.IsEnabled = false;
                                          bool userDirExists = false;
                                          if (!Directory.Exists(baseDir))
                                              Directory.CreateDirectory(baseDir);
                                          try
                                          {
                                              if (!Directory.Exists(userDir))
                                                  Directory.CreateDirectory(userDir);
                                              userDirExists = true;
                                          }
                                          catch (Exception ex)
                                          {
                                              HelperClasses.HelperFunctions.LogException(ex);
                                          }
                                          string outDir = baseDir;
                                          string outFile = baseDir + "\\" + message.ExtraInfo1;
                                          if (userDirExists)
                                          {
                                              outFile = userDir + "\\" + message.ExtraInfo1;
                                              outDir = userDir;
                                          }
                                          (downloadLink.Inlines.FirstInline as Run).Text = "\r\nDownloading... ";
                                          WebClient client = new WebClient();
                                          client.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
                                          client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
                                          client.DownloadFileAsync(new Uri(downloadURL), outFile);
                                          (cancelLink.Inlines.FirstInline as Run).Text = "\r\nCancel.";
                                          cancelLink.IsEnabled = true;
                                          cancelLink.Click += (sender1, e) =>
                                          {
                                              client.CancelAsync();
                                              (cancelLink.Inlines.FirstInline as Run).Text = "";
                                              cancelLink.IsEnabled = false;
                                          };
                                          openLink.Click += (sender1, e) =>
                                          {
                                              try
                                              {
                                                  System.Diagnostics.Process.Start("explorer.exe", "/select, " + outFile);
                                              }
                                              catch (Exception ex)
                                              {
                                                  HelperFunctions.LogException(ex);
                                              }
                                          };
                                          System.ComponentModel.AsyncCompletedEventHandler completed = (s, completedParms) =>
                                          {
                                              _ongoingXferCount--;
                                              (cancelLink.Inlines.FirstInline as Run).Text = "";
                                              cancelLink.IsEnabled = false;
                                              downloadLink.IsEnabled = true;
                                              if (completedParms.Error == null && completedParms.Cancelled == false)
                                              {
                                                  downloadLink.IsEnabled = false;
                                                  (downloadLink.Inlines.FirstInline as Run).Text = "\r\nDownload completed! ";
                                                  openLink.IsEnabled = true;
                                                  (openLink.Inlines.FirstInline as Run).Text = "\r\nClick here to open the folder with the file.";
                                                  timeLeftRun.Text = "Completed.";
                                                  para.Inlines.Add(openLink);
                                              }
                                              else
                                                  if (completedParms.Cancelled == true)
                                                  {
                                                      downloadLink.IsEnabled = false;
                                                      (downloadLink.Inlines.FirstInline as Run).Text = "\r\nDownload Cancelled!";
                                                      timeLeftRun.Text = "Cancelled.";
                                                  }
                                                  else
                                                  {
                                                      downloadLink.IsEnabled = false;
                                                      (downloadLink.Inlines.FirstInline as Run).Text = "\r\nDownload failed!";
                                                      timeLeftRun.Text = "Error.";
                                                  }
                                          };
                                          client.DownloadFileCompleted += completed;
                                          DownloadProgressChangedEventHandler progressChangedHandler = (s, changeParms) =>
                                          {
                                              pb.Value = changeParms.ProgressPercentage;
                                              downloadedBytesRun.Text = ((double)changeParms.BytesReceived / (1024 * 1024)).ToString("0.000MB");
                                              DateTime currTime = DateTime.Now;
                                              TimeSpan elapsed = currTime - startTime;
                                              double seconds = elapsed.TotalSeconds;
                                              double speed = changeParms.BytesReceived / seconds;
                                              speed = speed / 1024;
                                              downloadSpeedRun.Text = speed.ToString("0.00KBs");
                                              timeLeftRun.Text = new TimeSpan(0, 0, (int)((changeParms.TotalBytesToReceive - changeParms.BytesReceived) / (speed * 1024))).ToString();
                                          };
                                          client.DownloadProgressChanged += progressChangedHandler;
                                      };

                para.Inlines.Add(downloadLink);


                _incomingTB.Document.Blocks.Add(para);

                if (_scrollMessagesCB.IsChecked == true)
                {
                    _messageScroller.ScrollToBottom();
                }

                if (!AssociatedTab.IsSelected)
                {
                    AssociatedSelector.FlashUnderline();
                    HelperClasses.Registry.MainWindow.SetClickableNotification("New file transfer received from " + AssociatedClient.DisplayName, Colors.White, Colors.Teal, AssociatedClient.Username, AssociatedSelector);
                }
                if (HelperClasses.Registry.MainWindow.IsVisible == false && HelperClasses.Registry.Settings.ShowNewMessagePopup)
                {
                    PopupWindow popup = new PopupWindow();
                    popup.ShowWindow(10, message, senderInfo, AssociatedClient);
                }
            }
            catch (Exception ex)
            {
                HelperFunctions.LogException(ex);
            }
        }

        void downloadLink_Click(object sender, RoutedEventArgs e)
        {


            
        }

        void open_Click(object sender, RoutedEventArgs e)
        {
            Hyperlink link = sender as Hyperlink;
            string file = link.Tag as string;
            try
            {
                System.Diagnostics.Process.Start("explorer.exe","/select, "+file);
            }
            catch (Exception ex)
            {
                HelperFunctions.LogException(ex);
            }
        }

        private void ReceiveTextMessage(WGMClient.WGMSvc.WGMMessage message)
        {
            try
            {
                WGMLocalClient senderInfo;
                var sender = HelperClasses.Registry.MainWindow.GetCLItem(message.SenderLogon);
                if (sender == null)
                    senderInfo = HelperClasses.Registry.MyInfo;
                else
                    senderInfo = sender.AssociatedClient;
                if (senderInfo == null)
                    return;
                Paragraph para = new Paragraph();

                SolidColorBrush introBrush = new SolidColorBrush(HelperClasses.Registry.Settings.SystemFontColour);

                SolidColorBrush messageBrush = new SolidColorBrush(senderInfo.UserColor);

                string runIntro = "";
                if (HelperClasses.Registry.Settings.ShowMessageTimeStamps == true)
                    runIntro += "<" + message.ServerTimeStamp.ToString() + "> ";

                Run introRun = new Run(runIntro + (message.SenderLogon=="SERVER"?"Server": senderInfo.DisplayName) + " says:\r\n");
                introRun.FontFamily = new FontFamily(HelperClasses.Registry.Settings.SystemFontFamily);
                introRun.FontSize = HelperClasses.Registry.Settings.SystemFontSize;
                introRun.Foreground = introBrush;
                if (HelperClasses.Registry.Settings.IsSystemFontBold)
                    introRun.FontWeight = FontWeights.Bold;
                if (HelperClasses.Registry.Settings.IsSystemFontItalics)
                    introRun.FontStyle = FontStyles.Italic;
                para.Inlines.Add(introRun);

                string messageContent = message.Message as string;

                string[] delim = { "~!~@delim@~!~" };
                Regex linkMatch = new Regex("(?:^|[\\s\\[\\]\\}\\{\\(\\)\\\'\\\"<>])((?:(?:https?|gopher|ftp|file|irc):\\/\\/|www\\.)[a-zA-Z0-9\\.\\-=;&%\\?]+(?:\\/?[a-zA-Z0-9\\.\\-=;:'{}><,~`*_!@^#$|+&%\\?]*)*)");
                MatchCollection matches = linkMatch.Matches(messageContent);

                foreach (Match link in matches)
                {
                    messageContent = messageContent.Replace(link.Value, delim[0]);
                }
                string[] messageRuns = messageContent.Split(delim, StringSplitOptions.None);
                int insCount = 0;
                foreach (string messageText in messageRuns)
                {
                    Run messageRun = new Run(messageText);
                    messageRun.FontFamily = senderInfo.FontFace;
                    messageRun.FontSize = senderInfo.FontSize;
                    if (senderInfo.IsFontBold)
                        messageRun.FontWeight = FontWeights.Bold;
                    if (senderInfo.IsFontItalics)
                        messageRun.FontStyle = FontStyles.Italic;

                    messageRun.Foreground = messageBrush;
                    para.Inlines.Add(messageRun);

                    if (insCount < matches.Count)
                    {
                        Hyperlink hp = new Hyperlink(new Run(matches[insCount].Value));
                        if (HelperClasses.Registry.Settings.ShowImagePreviews)
                        {
                            if (matches[insCount].Value.EndsWith(".jpg", true, CultureInfo.InvariantCulture) ||
                                matches[insCount].Value.EndsWith(".jpeg", true, CultureInfo.InvariantCulture) ||
                                matches[insCount].Value.EndsWith(".png", true, CultureInfo.InvariantCulture) ||
                                matches[insCount].Value.EndsWith(".gif", true, CultureInfo.InvariantCulture) ||
                                matches[insCount].Value.EndsWith(".bmp", true, CultureInfo.InvariantCulture))
                            {
                                RelaySvc.ServiceSoapClient clientSvc = new WGMClient.RelaySvc.ServiceSoapClient();
                                Image image = new Image();
                                ToolTipService.SetShowDuration(image, Int16.MaxValue);
                                string url = matches[insCount].Value;

                                para.Inlines.Add(image);
                                ThreadPool.QueueUserWorkItem
                                (
                                    delegate
                                    {
                                        try
                                        {
                                            string file = clientSvc.GetWebsiteThumbnail(url, -1, -1, -1, -1);
                                            string urlImage = "http://www.hartlabs.com/downloads/wgm/uploads/" + file;
                                            string baseDir = (HelperClasses.Registry.WorkingDir + "Temp");
                                            if (!Directory.Exists(baseDir))
                                                Directory.CreateDirectory(baseDir);
                                            string downloadTarget = baseDir + "\\" + file;
                                            WebClient client = new WebClient();
                                            client.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
                                            client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
                                            client.DownloadFile(new Uri(urlImage), downloadTarget);
                                            this.Dispatcher.Invoke
                                            (
                                                new Action
                                                (
                                                    delegate
                                                    {
                                                        try
                                                        {
                                                            MemoryStream ms = new MemoryStream();
                                                            FileStream stream = new FileStream(downloadTarget, FileMode.Open, FileAccess.Read);
                                                            ms.SetLength(stream.Length);
                                                            stream.Read(ms.GetBuffer(), 0, (int)stream.Length);

                                                            ms.Flush();
                                                            stream.Close();


                                                            BitmapImage src = new BitmapImage();
                                                            src.BeginInit();
                                                            src.StreamSource = ms;
                                                            src.EndInit();
                                                            image.Source = src;
                                                            image.Width = HelperClasses.Registry.Settings.ImagePreviewWidth;
                                                            image.Height = HelperClasses.Registry.Settings.ImagePreviewHeight;
                                                            image.Cursor = Cursors.Hand;
                                                            image.ToolTip = new Image() { Source = src };
                                                            image.MouseLeftButtonDown += (imageSender, imageparms) =>
                                                            {
                                                                
                                                                Window popUp = new Window();
                                                                Grid content = new Grid();
                                                                Image windowImage = new Image();
                                                                windowImage.Source = src;
                                                                Button saveButton = new Button();
                                                                saveButton.Width = 120;
                                                                saveButton.Height = 25;
                                                                saveButton.HorizontalAlignment = HorizontalAlignment.Right;
                                                                saveButton.VerticalAlignment = VerticalAlignment.Bottom;
                                                                saveButton.Margin = new Thickness(10);
                                                                saveButton.Opacity = 0.5;
                                                                saveButton.Content = "Save Image";
                                                                saveButton.Click += (buttonSender, buttonParms) =>
                                                                {
                                                                    SaveFileDialog sfd = new SaveFileDialog();
                                                                    if (sfd.ShowDialog() == true)
                                                                    {
                                                                        try
                                                                        {
                                                                            File.Copy(downloadTarget, sfd.FileName);
                                                                        }
                                                                        catch (Exception ex)
                                                                        {
                                                                            HelperClasses.HelperFunctions.LogException(ex);
                                                                            HelperClasses.Registry.MainWindow.SetDropDownMessage("Unable to save file.", Colors.White, Colors.Red, 5000);
                                                                        }
                                                                    }
                                                                };

                                                                Canvas.SetZIndex(saveButton, 1);
                                                                ScrollViewer scroller = new ScrollViewer();
                                                                scroller.Content = windowImage;
                                                                scroller.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
                                                                scroller.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
                                                                content.Children.Add(scroller);
                                                                content.Children.Add(saveButton);
                                                                popUp.Title = "WGM Image Viewer";
                                                                popUp.Content = content;
                                                                popUp.Width = WGMClient.HelperClasses.Registry.MainWindow.Width;
                                                                popUp.Height = WGMClient.HelperClasses.Registry.MainWindow.Height;
                                                                popUp.Owner = WGMClient.HelperClasses.Registry.MainWindow;
                                                                popUp.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                                                                popUp.Show();
                                                            };
                                                        }
                                                        catch (Exception ex)
                                                        {
                                                            HelperClasses.HelperFunctions.LogException(ex);
                                                        }
                                                    }
                                                )
                                            );
                                            

                                        }
                                        catch (Exception ex)
                                        {
                                            HelperClasses.HelperFunctions.LogException(ex);
                                        }

                                    }
                                );
                                
                            }
                        }

                        hp.FontFamily = messageRun.FontFamily;
                        hp.FontSize = messageRun.FontSize + 1;
                        hp.FontStyle = messageRun.FontStyle;
                        hp.TextDecorations = messageRun.TextDecorations;
                        hp.Foreground = new SolidColorBrush(Colors.Blue);
                        hp.Click += new RoutedEventHandler(hp_Click);
                        hp.Tag = matches[insCount].Value.Trim();
                        para.Inlines.Add(hp);
                    }
                    insCount++;
                }

                _incomingTB.Document.Blocks.Add(para);
                if (_scrollMessagesCB.IsChecked == true)
                {
                    _messageScroller.ScrollToBottom();
                }

                if (!AssociatedTab.IsSelected)
                {
                    AssociatedSelector.FlashUnderline();
                    HelperClasses.Registry.MainWindow.SetClickableNotification("New message received from " + AssociatedClient.DisplayName, Colors.White, Colors.OrangeRed, AssociatedClient.Username, AssociatedSelector);
                }
                if (HelperClasses.Registry.MainWindow.IsVisible == false && HelperClasses.Registry.Settings.ShowNewMessagePopup)
                {
                    PopupWindow popup = new PopupWindow();
                    popup.ShowWindow(10, message, senderInfo, AssociatedClient);
                }
                if (HelperClasses.HelperFunctions.GetForegroundWindow() != HelperClasses.Registry.MainWindow.WindowHandle)
                {
                    if (message.SenderLogon != HelperClasses.Registry.Username && PlaySound)
                    {
                        HelperClasses.HelperFunctions.PlayMessageSound();
                    }
                }
            }
            catch (Exception ex)
            {
                HelperClasses.HelperFunctions.LogException(ex);
            }
        }



        void hp_Click(object sender, RoutedEventArgs e)
        {
            Hyperlink link = sender as Hyperlink;
            try
            {
                System.Diagnostics.Process.Start(link.Tag.ToString());
                //WGMSvc.ServiceSoapClient client = new WGMClient.WGMSvc.ServiceSoapClient();
                //string url = link.Tag.ToString();
                //if (!url.StartsWith("http://"))
                //    url = "http://" + url;
                //byte[] arr = client.GetWebStream(url);
                //WebBrowser browser = new WebBrowser();
                //browser.NavigateToStream (new MemoryStream(arr));

                //SuppressScriptErrors(browser, true);
                //Window brs = new Window();
                //brs.Content = browser;
                //brs.Show();
                //browser.Navigating += new NavigatingCancelEventHandler(browser_Navigating);
                //browser.Tag = null;
            }
            catch (Exception ex)
            {

            }

        }

        void browser_Navigating(object sender, NavigatingCancelEventArgs e)
        {
            try
            {
                WebBrowser browser = sender as WebBrowser;


                WGMSvc.ServiceSoapClient client = new WGMClient.WGMSvc.ServiceSoapClient();
                byte[] arr = client.GetWebStream(e.Uri.ToString());

                browser.NavigateToStream(new MemoryStream(arr));
            }
            catch { }


        }
        public void SuppressScriptErrors(System.Windows.Controls.WebBrowser wb, bool Hide)
        {
            FieldInfo fi = typeof(System.Windows.Controls.WebBrowser).GetField(
                "_axIWebBrowser2",
                BindingFlags.Instance | BindingFlags.NonPublic);

            if (fi != null)
            {
                object browser = fi.GetValue(wb);

                if (browser != null)
                {
                    browser.GetType().InvokeMember("Silent", BindingFlags.SetProperty,
                        null, browser, new object[] { Hide });

                }
            }
        }

        public void NotifyLocalMessage(LocalMessage message)
        {
            this.Dispatcher.Invoke
            (
                new Action
                (
                    delegate
                    {
                        if (message.MessageType == LocalMessageTypes.MY_INFO_CHANGED)
                            SetOutgoingTB();
                        if (message.MessageType == LocalMessageTypes.CONNECTION_FAULTED && message.MessageData != null && message.MessageData is WGMSvc.WGMMessage)
                        {
                            var failedMessage = message.MessageData as WGMSvc.WGMMessage;
                            if (failedMessage.MessageType == WGMClient.WGMSvc.MessageTypes.GLOBAL_MESSAGE && this.IsMainWindow)
                            {
                                ReceiveFailedTextMessage(failedMessage);
                            }
                        }
                        if (message.MessageType == LocalMessageTypes.SYSTEM_OPTIONS_CHANGED)
                        {
                            _contactInfo.HasImage = HelperClasses.Registry.Settings.ShowContactImages;
                        }
                    }
                )
            );
        }



        private void OnOutgoingKeyUp(object sender, KeyEventArgs e)
        {
            if ((DateTime.Now - _lastType).TotalSeconds > 4)
            {
                _lastType = DateTime.Now;
                if (IsMainWindow)
                {
                    HelperClasses.Registry.Engine.SendMessageToServer(new WGMClient.WGMSvc.WGMMessage() { SenderLogon = HelperClasses.Registry.Username, MessageType = WGMClient.WGMSvc.MessageTypes.USER_TYPING_GLOBAL });
                }
                else
                {
                    HelperClasses.Registry.Engine.SendMessageToServer(new WGMClient.WGMSvc.WGMMessage() { SenderLogon = HelperClasses.Registry.Username, ReceiverLogon = AssociatedClient.Username, MessageType = WGMClient.WGMSvc.MessageTypes.USER_TYPING_PRIVATE });
                }
            }
            
            if (e.Key == Key.Enter && e.KeyboardDevice.Modifiers == ModifierKeys.Control)
            {
                _outgoingTB.CaretPosition.InsertLineBreak();
                _outgoingTB.CaretPosition = _outgoingTB.CaretPosition.DocumentEnd;

            }
            if (e.Key == Key.Enter && e.KeyboardDevice.Modifiers == ModifierKeys.None)
            {
                TextPointer from = _outgoingTB.CaretPosition.DocumentStart;
                TextPointer to = _outgoingTB.CaretPosition;
                _outgoingTB.Selection.Select(from, to);
                _outgoingTB.Selection.Text = _outgoingTB.Selection.Text.Remove(_outgoingTB.Selection.Text.Length - 2, 2);
                _outgoingTB.SelectAll();
                string messageText = _outgoingTB.Selection.Text;

                WGMSvc.WGMMessage newMessage = new WGMSvc.WGMMessage();
                if (IsMainWindow)
                {
                    newMessage.MessageType = WGMSvc.MessageTypes.GLOBAL_MESSAGE;
                    newMessage.SenderLogon = HelperClasses.Registry.Username;
                    newMessage.Message = messageText.Trim();
                }
                else
                {
                    newMessage.MessageType = WGMSvc.MessageTypes.PRIVATE_MESSAGE;
                    newMessage.SenderLogon = HelperClasses.Registry.Username;
                    newMessage.ReceiverLogon = AssociatedClient.Username;
                    newMessage.Message = messageText.Trim();
                }

                _outgoingTB.Selection.Text = "";
                _outgoingTB.Selection.ClearAllProperties();
                SetOutgoingTB();
                if ((newMessage.Message as string).Trim() == "")
                    return;

                HelperClasses.Registry.Engine.SendMessageToServer(newMessage);
            }
        }
        private void ReceiveFailedTextMessage(WGMClient.WGMSvc.WGMMessage message)
        {
            if (message == null)
                return;

            var sender = HelperClasses.Registry.MyInfo;

            Paragraph para = new Paragraph();


            SolidColorBrush introBrush = new SolidColorBrush(Colors.Red);
            SolidColorBrush messageBrush = new SolidColorBrush(sender.UserColor);
            string runIntro = "";
            if (HelperClasses.Registry.Settings.ShowMessageTimeStamps == true)
                runIntro += "<" + DateTime.Now + "> ";

            Run introRun = new Run(runIntro + " Unable to send message:\r\n");
            introRun.FontFamily = new FontFamily( HelperClasses.Registry.Settings.SystemFontFamily);
            introRun.FontSize = HelperClasses.Registry.Settings.SystemFontSize;
            if (HelperClasses.Registry.Settings.IsSystemFontBold)
                introRun.FontWeight = FontWeights.Bold;
            if (HelperClasses.Registry.Settings.IsSystemFontItalics)
                introRun.FontStyle = FontStyles.Italic;

            introRun.Foreground = introBrush;
            para.Inlines.Add(introRun);
            
            
            string messageContent = message.Message as string;
            string[] delim = { "~!~@delim@~!~" };
            Regex linkMatch = new Regex("(?:^|[\\s\\[\\]\\}\\{\\(\\)\\\'\\\"<>])((?:(?:https?|gopher|ftp|file|irc):\\/\\/|www\\.)[a-zA-Z0-9\\.\\-=;&%\\?]+(?:\\/?[a-zA-Z0-9\\.\\-=;:'{}><,~`*_!@^#$|+&%\\?]*)*)");
            MatchCollection matches = linkMatch.Matches(messageContent);

            foreach (Match link in matches)
            {
                messageContent = messageContent.Replace(link.Value, delim[0]);
            }
            string[] messageRuns = messageContent.Split(delim, StringSplitOptions.None);
            int insCount = 0;
            foreach (string messageText in messageRuns)
            {
                Run messageRun = new Run(messageText);
                messageRun.FontFamily = WGMClient.HelperClasses.Registry.MyInfo.FontFace;
                messageRun.FontSize = WGMClient.HelperClasses.Registry.MyInfo.FontSize;
                if (WGMClient.HelperClasses.Registry.MyInfo.IsFontBold)
                    messageRun.FontWeight = FontWeights.Bold;
                if (WGMClient.HelperClasses.Registry.MyInfo.IsFontItalics)
                    messageRun.FontStyle = FontStyles.Italic;

                messageRun.Foreground = messageBrush;
                para.Inlines.Add(messageRun);

                if (insCount < matches.Count)
                {
                    Hyperlink hp = new Hyperlink(new Run(matches[insCount].Value));
                    hp.FontFamily = messageRun.FontFamily;
                    hp.FontSize = messageRun.FontSize + 1;
                    hp.FontStyle = messageRun.FontStyle;
                    hp.TextDecorations = messageRun.TextDecorations;
                    hp.Foreground = new SolidColorBrush(Colors.Blue);
                    hp.Click += new RoutedEventHandler(hp_Click);
                    hp.Tag = matches[insCount].Value.Trim();
                    para.Inlines.Add(hp);
                }
                insCount++;
            }

            Hyperlink resendLink = new Hyperlink(new Run("\r\n\r\nClick here to resend"));
            resendLink.FontFamily = introRun.FontFamily;
            resendLink.FontStyle = introRun.FontStyle;
            resendLink.FontSize = introRun.FontSize;
            resendLink.TextDecorations = introRun.TextDecorations;
            resendLink.Foreground = new SolidColorBrush(Colors.Blue);
            resendLink.Click += new RoutedEventHandler(resendLink_Click);
            resendLink.Tag = message;
            para.Inlines.Add(resendLink);
            _incomingTB.Document.Blocks.Add(para);

            if (_scrollMessagesCB.IsChecked == true)
            {
                _messageScroller.ScrollToBottom();
            }

            if (!AssociatedTab.IsSelected)
            {
                AssociatedSelector.FlashUnderline();
                HelperClasses.Registry.MainWindow.SetClickableNotification("New message received from " + AssociatedClient.DisplayName, Colors.White, Colors.OrangeRed, AssociatedClient.Username, AssociatedSelector);
            }
        }

        void resendLink_Click(object sender, RoutedEventArgs e)
        {
            Hyperlink link = sender as Hyperlink;
            WGMSvc.WGMMessage message = link.Tag as WGMSvc.WGMMessage;
            HelperClasses.Registry.Engine.SendMessageToServer(message);
        }
        private void OnClearMessages(object sender, MouseButtonEventArgs e)
        {
            this.Dispatcher.Invoke
            (
                new Action
                (
                    delegate
                    {
                        try
                        {
                            if (_ongoingXferCount > 0)
                            {
                                MessageBox.Show("There are ongoing file transfers, please wait until they are completed to clear messages.", "WGM", MessageBoxButton.OK, MessageBoxImage.Information);
                                return;
                                
                            }
                            _incomingTB.Document.Blocks.Clear();
                        }
                        catch { }
                    }
                )
            );
        }

        private void OnSendFile(object sender, MouseButtonEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = true;
            if (ofd.ShowDialog() == true)
            {
                foreach(var filename in ofd.FileNames)
                SendFile(filename);
            }
        }

        private void SendFile(string filePath)
        {
            
            ProgressBar pb = new ProgressBar();
            Paragraph para = new Paragraph();
            SolidColorBrush introBrush = new SolidColorBrush(Colors.Red);
            SolidColorBrush messageBrush = new SolidColorBrush(Colors.Gray);
            string runIntro = "";
            if (HelperClasses.Registry.Settings.ShowMessageTimeStamps == true)
                runIntro += "<" + DateTime.Now + "> ";
            Run introRun = new Run(runIntro + " Sending File:\r\n"+filePath+"\r\n");

            introRun.FontFamily = new FontFamily(HelperClasses.Registry.Settings.SystemFontFamily);
            introRun.FontSize = HelperClasses.Registry.Settings.SystemFontSize;
            if (HelperClasses.Registry.Settings.IsSystemFontBold)
                introRun.FontWeight = FontWeights.Bold;
            if (HelperClasses.Registry.Settings.IsSystemFontItalics)
                introRun.FontStyle = FontStyles.Italic;

            introRun.Foreground = introBrush;
            Run sizeIntroRun = new Run("\r\nFile Size: ");
            Run sizeRun = new Run("");
            Run speedRunIntro = new Run("\r\nTransfer Speed: ");
            Run speedRun = new Run("0KBs");
            Run elapsedIntroRun = new Run("\r\nTime elapsed: ");
            Run elapsedRun = new Run("");
            Run leftIntroRun = new Run("\r\nTime left: ");
            Run leftRun = new Run("");

            Run cancelRun = new Run("\r\nCancel Transfer");
            cancelRun.Cursor = Cursors.Hand;
            
            cancelRun.Foreground = new SolidColorBrush(Colors.Blue);

            Run resendRun = new Run("\r\nResend");
            resendRun.Cursor = Cursors.Hand;

            resendRun.Foreground = new SolidColorBrush(Colors.Blue);

            pb.Width = 200;
            pb.Height = 5;
            pb.Maximum = 100;
            pb.Minimum = 0;
            ThreadPool.QueueUserWorkItem
            (
                delegate
                {
                    try
                    {
                        FileInfo fi = new FileInfo(filePath);
                        string id = "";
                        MD5 md5 = new MD5CryptoServiceProvider();

                        
                        if (fi.Length > (1024 * 1024 * 15))
                        {
                            MessageBox.Show("Please select a file smaller than 15 MB\r\n" + filePath, "WGM Send File Error", MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                        try
                        {
                            _ongoingXferCount++;
                            
                            WGMClient.HelperClasses.Registry.MainWindow.SetDropDownMessage("Sending File To Server: " + fi.Name, "_upload_" + fi.Name);
                            bool ftpSuccess = false;
                            WGMSvc.WGMMessage response = null;
                            bool cancel = false;
                            //try
                            //{
                            //    id = FileUploader.FileUploader.UploadFile(filePath);
                            //    ftpSuccess = true;
                            //}
                            //catch
                            {
                                if (fi.Length > (1024 * 1024 * 15))
                                {
                                    MessageBox.Show("Please select a file smaller than 15 MB\r\n" + filePath, "WGM Send File Error", MessageBoxButton.OK, MessageBoxImage.Error);
                                    return;
                                }
                                FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                                byte[] retVal = md5.ComputeHash(fs);

                                StringBuilder sb = new StringBuilder();
                                for (int i = 0; i < retVal.Length; i++)
                                {
                                    sb.Append(retVal[i].ToString("x2"));
                                }
                                id = sb.ToString();
                                int bytesToRead = 96000;
                                byte[] data = new byte[bytesToRead];
                                long totalBytesRead = 0;
                                int currentBytesRead = 0;

                                DateTime startTime = DateTime.Now;
                                this.Dispatcher.Invoke
                                (
                                    new Action
                                    (
                                        delegate 
                                        { 
                                            para.Inlines.Add(introRun); 
                                            para.Inlines.Add(pb);
                                            para.Inlines.Add(sizeIntroRun);
                                            para.Inlines.Add(sizeRun);
                                            para.Inlines.Add(speedRunIntro); 
                                            para.Inlines.Add(speedRun) ;
                                            para.Inlines.Add(elapsedIntroRun);
                                            para.Inlines.Add(elapsedRun);
                                            para.Inlines.Add(leftIntroRun);
                                            para.Inlines.Add(leftRun);
                                            para.Inlines.Add(cancelRun);
                                            _incomingTB.Document.Blocks.Add(para);
                                            sizeRun.Text = ((double)fi.Length / (1024 * 1024)).ToString("0.000MB");
                                            cancelRun.MouseDown += delegate { cancel = true; cancelRun.Text = ""; cancelRun.IsEnabled = false; leftRun.Text = "Cancelled"; };
                                            if (_scrollMessagesCB.IsChecked == true)
                                            {
                                                _messageScroller.ScrollToBottom();
                                            }
                                        }
                                    )
                                );
                                WGMSvc.ServiceSoapClient client = new WGMClient.WGMSvc.ServiceSoapClient();
                                bool firstPacket = true;
                                do
                                {
                                    fs.Seek(totalBytesRead,SeekOrigin.Begin);
                                    currentBytesRead = fs.Read(data, 0, bytesToRead);
                                    
                                    WGMSvc.WGMMessage packet = new WGMClient.WGMSvc.WGMMessage();
                                    packet.MessageType = WGMClient.WGMSvc.MessageTypes.FILE_XFER_PART_REQUEST;
                                    packet.Message = data;
                                    packet.ExtraInfo1 = id.ToString();
                                    packet.ExtraInfo2 = totalBytesRead;
                                    packet.ExtraInfo3 = currentBytesRead;
                                    packet.ExtraInfo4 = firstPacket;
                                    totalBytesRead += currentBytesRead;
                                    bool sendFailure = false;
                                    int tries = 1;
                                    do
                                    {
                                        try
                                        {
                                            response = client.HandleServerMessage(packet);

                                            firstPacket = false;
                                        }
                                        catch
                                        {
                                            tries++;
                                            sendFailure = true;
                                        }
                                    } while (sendFailure && tries < 3);
                                    DateTime curr = DateTime.Now;
                                    TimeSpan elapsed = curr - startTime;
                                    double seconds = elapsed.TotalSeconds;
                                    double speed = totalBytesRead / seconds;
                                    speed = speed / 1024;

                                    this.Dispatcher.Invoke
                                    (
                                        new Action
                                        (
                                            delegate 
                                            {
                                                if (!cancel)
                                                {
                                                    pb.Value = ((double)totalBytesRead * 100) / fs.Length;
                                                    speedRun.Text = speed.ToString("0.00KBs");
                                                    elapsedRun.Text = new TimeSpan(0, 0, (int)seconds).ToString();
                                                    leftRun.Text = new TimeSpan(0, 0, (int)((fi.Length - totalBytesRead) / (speed * 1024))).ToString();
                                                }
                                            }
                                        )
                                    );
                                    if (response != null && response.ExtraInfo1 != null && response.ExtraInfo1 is bool && (bool)response.ExtraInfo1 == true)
                                    {
                                        this.Dispatcher.Invoke
                                        (
                                            new Action
                                            (
                                                delegate
                                                {
                                                    pb.Value = 100;
                                                }
                                            )
                                        );
                                        break;
                                    }
                                    if (cancel)
                                    {
                                        fs.Close();
                                        return;
                                    }
                                    
                                }
                                while (currentBytesRead > 0);

                                fs.Close();

                            }
                            this.Dispatcher.Invoke
                            (
                                new Action
                                (
                                    delegate
                                    {                                                                              
                                        leftRun.Text = "Completed";
                                        cancelRun.Text = "";
                                        cancelRun.IsEnabled = false;
                                    }
                                )
                            );

                            WGMSvc.WGMMessage newMessage = new WGMSvc.WGMMessage();
                            newMessage.SenderLogon = HelperClasses.Registry.Username;
                            if (IsMainWindow)
                            {
                                newMessage.MessageType = WGMSvc.MessageTypes.GLOBAL_FILE_XFER;
                            }
                            else
                            {
                                newMessage.MessageType = WGMSvc.MessageTypes.PRIVATE_FILE_XFER;
                                newMessage.ReceiverLogon = AssociatedClient.Username;
                            }

                            newMessage.ExtraInfo1 = fi.Name;
                            newMessage.ExtraInfo2 = ((double)fi.Length / (1024 * 1024)).ToString("0.000MB");

                            newMessage.ExtraInfo3 = id.ToString() + ".zip";
                            newMessage.ExtraInfo4 = fi.Length;


                            WGMClient.HelperClasses.Registry.Engine.SendMessageToServer(newMessage);
                            this.Dispatcher.Invoke
                            (
                                new Action
                                (
                                    delegate
                                    {
                                        para.Inlines.Add(resendRun);
                                        resendRun.MouseDown += delegate
                                        {
                                            WGMClient.HelperClasses.Registry.Engine.SendMessageToServer(newMessage);
                                        };
                                    }
                                )
                            );
                        }

                        catch (Exception ex)
                        {
                            this.Dispatcher.Invoke
                            (
                                new Action
                                (
                                    delegate
                                    {
                                        leftRun.Text = "Transfer Error.";
                                        cancelRun.Text = "";
                                        cancelRun.IsEnabled = false;
                                    }
                                )
                            );
                            WGMClient.HelperClasses.Registry.MainWindow.SetDropDownMessage("Error sending file to server: " + fi.Name, Colors.White, Colors.Red, 5000);
                            HelperFunctions.LogException(ex);
                        }
                        finally
                        {
                            WGMClient.HelperClasses.Registry.MainWindow.ClearDropDownMessage("_upload_" + fi.Name);
                            _ongoingXferCount--;
                        }
                    }
                    catch (Exception ex)
                    {
                        HelperClasses.HelperFunctions.LogException(ex);
                        WGMClient.HelperClasses.Registry.MainWindow.SetDropDownMessage("Errr, you can't do that!", Colors.White, Colors.Red, 5000);
                    }
                }
            );
        }

        private void OnDrop(object sender, DragEventArgs e)
        {
            try
            {
                string[] droppedFilePaths = e.Data.GetData(DataFormats.FileDrop, true) as string[];
                foreach (var filePath in droppedFilePaths)
                {
                    SendFile(filePath);
                }
            }
            catch (Exception ex)
            {
                HelperClasses.HelperFunctions.LogException(ex);
                WGMClient.HelperClasses.Registry.MainWindow.SetDropDownMessage("Errr, you can't do that!", Colors.White, Colors.Red, 5000);

            }
        }

        private void OnDragOver(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.All;

            e.Handled = true;
        }

        private void OnSoundChk(object sender, RoutedEventArgs e)
        {
            HelperClasses.Registry.Settings.UpdateSoundList(AssociatedClient.Username, _playSoundChk.IsChecked.Value);
        }
        public bool PlaySound 
        {
            get { return _playSoundChk.IsChecked.Value; }
            set { _playSoundChk.IsChecked = value; }
        }

        private void OnSearchGoogleClick(object sender, RoutedEventArgs e)
        {
            string text = _incomingTB.Selection.Text;
            try
            {
                System.Diagnostics.Process.Start("http://www.google.com/#q=" + text);
            }
            catch { }
        }

        private void OnCopy(object sender, RoutedEventArgs e)
        {
            try
            {
                Clipboard.SetText(_incomingTB.Selection.Text);
            }
            catch { }
            
        }

        private void OnContextOpening(object sender, ContextMenuEventArgs e)
        {
            if (_incomingTB.Selection.Text.Trim() == "")
            {
                e.Handled = true;
            }
        }

        private void OnDefineClick(object sender, RoutedEventArgs e)
        {
            string text = _incomingTB.Selection.Text;
            try
            {
                System.Diagnostics.Process.Start("http://dictionary.reference.com/browse/" + text);
            }
            catch { }
        }

    }
}
